<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="XVTfs" id="XVTfs"><span data-lake-id="ue5370488" id="ue5370488">典型回答</span></h1>
  <p data-lake-id="u6b998020" id="u6b998020"><br></p>
  <p data-lake-id="ud65e7992" id="ud65e7992"><span data-lake-id="u8b73bedd" id="u8b73bedd">工作中常用的设计模式有很多，如单例、工厂、策略、模板等。</span><strong><span data-lake-id="u2cfb26c6" id="u2cfb26c6">一般在工作中，是可以把策略、工厂和模板一起结合着来使用的。</span></strong></p>
  <p data-lake-id="u9fcd3508" id="u9fcd3508"><span data-lake-id="u095bb02c" id="u095bb02c">​</span><br></p>
  <p data-lake-id="ue9f6fea9" id="ue9f6fea9"><span data-lake-id="uf59b2f5c" id="uf59b2f5c">当我们需要有多个具体的策略服务的时候，那不同的内容放到策略服务中，那些公共的东西就可以抽象出来放到模板方法中了。那这些策略服务该如何管理呢？什么时候用什么策略服务呢？这时候就可以借助工厂来管理这些服务。</span></p>
  <p data-lake-id="ua557277e" id="ua557277e"><span data-lake-id="u9b05fe49" id="u9b05fe49">​</span><br></p>
  <p data-lake-id="u0b9df338" id="u0b9df338"><span data-lake-id="u4ca9c3bf" id="u4ca9c3bf">如以下例子， 我们需要定义一个支付服务，里面有一个支付方法：</span></p>
  <p data-lake-id="u95e22c80" id="u95e22c80"><span data-lake-id="ua6780430" id="ua6780430">​</span><br></p>
  <pre lang="java"><code>
public interface PayService {
    public void pay(PayRequest payRequest);


}

class PayRequest {

}
</code></pre>
  <p data-lake-id="uf865a4e8" id="uf865a4e8"><br></p>
  <p data-lake-id="u7b658e32" id="u7b658e32"><span data-lake-id="udab20595" id="udab20595">这是一个单独的接口，只定义了一个方法，那么，我们再把所有支付渠道中公共的代码抽出来，定义一个抽象类：</span></p>
  <p data-lake-id="u8f6895f5" id="u8f6895f5"><span data-lake-id="ud3e91d15" id="ud3e91d15">​</span><br></p>
  <pre lang="java"><code>
public abstract class AbstractPayService implements PayService {

    @Override
    public void pay(PayRequest payRequest) {
      	//前置检查
        validateRequest(payRequest);
      	//支付核心逻辑
        doPay(payRequest);
      	//后置处理
        postPay(payRequest);
    }

    public abstract void doPay(PayRequest payRequest);

    private void postPay(PayRequest payRequest) {
        //支付成功的后置处理
    }

    public void validateRequest(PayRequest payRequest) {
        //参数检查
    }
}
</code></pre>
  <p data-lake-id="uf6bc568f" id="uf6bc568f"><br></p>
  <p data-lake-id="u128bf6d8" id="u128bf6d8"><span data-lake-id="uaac61b59" id="uaac61b59">这个抽象类中首先把pay方法给实现了，然后编排了几个其他的方法，这些公共的方法在抽象类中直接实现了，具体的支付核心实现，留给实现类去实现就行了。</span></p>
  <p data-lake-id="u5f18bf6e" id="u5f18bf6e"><span data-lake-id="uebf4525e" id="uebf4525e">​</span><br></p>
  <p data-lake-id="u55af9444" id="u55af9444"><span data-lake-id="uf2ef1e3f" id="uf2ef1e3f">然后我们就可以定义多个策略服务了：</span></p>
  <p data-lake-id="u3cd27704" id="u3cd27704"><span data-lake-id="u116225fa" id="u116225fa">​</span><br></p>
  <pre lang="java"><code>
@Service
public class AlipayPayService extends AbstractPayService {
    @Override
    public void doPay(PayRequest payRequest) {
        //支付宝支付逻辑
    }
}

@Service
public class WechatPayService extends AbstractPayService {
    @Override
    public void doPay(PayRequest payRequest) {
        //微信支付逻辑
    }
}
</code></pre>
  <p data-lake-id="ue89a3816" id="ue89a3816"><br></p>
  <p data-lake-id="u8bcc76d7" id="u8bcc76d7"><span data-lake-id="u7e688ea7" id="u7e688ea7">这些服务定义好了之后，需要有一个地方统一管理，那就定义一个工厂吧：</span></p>
  <p data-lake-id="u04f96d1e" id="u04f96d1e"><span data-lake-id="u503b8cdf" id="u503b8cdf">​</span><br></p>
  <pre lang="java"><code>
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class PayServiceFactory {

    @Autowired
    public Map&lt;String, PayService&gt; payServiceMap = new ConcurrentHashMap&lt;&gt;();

    public PayService getPayService(String payChannel) {
        // alipay -&gt; alipayPayService
        // wechat -&gt; wechatPayService
        return payServiceMap.get(payChannel + "PayService");
    }

}
</code></pre>
  <p data-lake-id="u063645bd" id="u063645bd"><span data-lake-id="u305d5d08" id="u305d5d08">​</span><br></p>
  <p data-lake-id="u3fd60bc8" id="u3fd60bc8"><span data-lake-id="u12b2c31a" id="u12b2c31a">在工厂中，把PayService的所有实现全部都注入到payServiceMap中，然后再需要用的是，直接调他的getPayService方法就行了。</span></p>
  <p data-lake-id="ufe6e6bb9" id="ufe6e6bb9"><span data-lake-id="ue2ec7d3e" id="ue2ec7d3e">​</span><br></p>
  <p data-lake-id="u654467b5" id="u654467b5"><span data-lake-id="u5f365fcc" id="u5f365fcc">这样，在使用的时候，只需要通过工厂就能获取对应的策略服务进行服务调用了：</span></p>
  <p data-lake-id="u772c7e06" id="u772c7e06"><span data-lake-id="ua43c2df0" id="ua43c2df0">​</span><br></p>
  <pre lang="java"><code>
public class PayDomainService {
    @Autowired
    PayServiceFactory payServiceFactory;

    public void pay(PayRequest payRequest) {
        String payChannel = payRequest.getPayChannel();
        payServiceFactory.getPayService(payChannel).pay(payRequest);
    }
}
</code></pre>
  <p data-lake-id="uf3b63edc" id="uf3b63edc"><br></p>
  <p data-lake-id="uad4754ca" id="uad4754ca"><span data-lake-id="u8f83c435" id="u8f83c435">以上，我们借助了Spring，结合了策略、模板以及工厂，实现了我们想要的功能，通过多种设计模式，减少重复代码，提升可维护性，也让代码更容易阅读和理解。</span></p>
 </body>
</html>